import 'dart:io';

import 'package:dio/io.dart';
import 'package:dio/dio.dart' hide FormData;
import 'package:dio/dio.dart' as dio show FormData;
import 'package:get/get.dart';
import '../../../storage/pref_utils.dart';
// import 'package:wohuifang/app/routes/app_pages.dart';

import '../api_client.dart';
import '../net_data.dart';
import 'dio_log.dart';

class TokenExpiredException implements Exception {
  final String message;
  TokenExpiredException(this.message);
}

class DioNetWorker extends NetWorker {
  final Dio _dio = Dio();

  DioNetWorker(String baseUrl) {
    _dio.options.baseUrl = baseUrl;
    _dio.options.followRedirects = false;
    _dio.options.maxRedirects = 0;
    _dio.interceptors.add(DioLogInterceptor(
      requestHeader: true,
      requestBody: true,
      responseBody: true,
      responseHeader: true,
      compact: false,
    ));

    // 添加响应拦截器处理token失效
    _dio.interceptors.add(
      InterceptorsWrapper(
        onResponse: (response, handler) {
          // 检查响应中是否包含token失效的错误码
          if (response.data is Map &&
              response.data['code'] != null &&
              response.data['code'].toString() == NetData.tokenExpired) {
            // 处理token失效，清除用户信息并跳转到登录页面
            _handleTokenExpired();
            // 继续传递响应，业务层可以做进一步处理
            handler.next(response);
          } else {
            handler.next(response);
          }
        },
        onError: (DioError error, ErrorInterceptorHandler handler) {
          // 处理服务器返回的token失效错误
          if (error.response != null &&
              error.response?.data is Map &&
              error.response?.data['code'] != null &&
              error.response?.data['code'].toString() == NetData.tokenExpired) {
            _handleTokenExpired();
          }
          handler.next(error);
        },
      ),
    );

    // 自动使用代理服务器
    _dio.httpClientAdapter = IOHttpClientAdapter(
      createHttpClient: () {
        final client = HttpClient();
        client.findProxy = HttpClient.findProxyFromEnvironment;
        client.badCertificateCallback =
            (X509Certificate cert, String host, int port) => true;
        return client;
      },
    );

    // if (AppConfig.useProxy) {
    //   (_dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate =
    //       (HttpClient client) {
    //     client.findProxy = (uri) {
    //       //proxy all request to localhost
    //       return "PROXY ${AppConfig.proxyAddress}";
    //     };
    //     client.badCertificateCallback =
    //         (X509Certificate cert, String host, int port) => true;
    //   };
    // }
  }

  // 处理token失效的方法
  void _handleTokenExpired() {
    // 防止重复处理
    if (!Get.isRegistered<RxBool>(tag: 'isHandlingTokenExpired')) {
      Get.put(false.obs, tag: 'isHandlingTokenExpired');
    }

    RxBool isHandling = Get.find<RxBool>(tag: 'isHandlingTokenExpired');

    // 如果已经在处理中，则不重复处理
    if (isHandling.value) return;

    isHandling.value = true;

    // 清除用户信息
    PrefUtils().removeToken().then((_) {
      // 确保在主线程中执行UI操作
      // Get.offAllNamed(Routes.LOGIN);

      // 可选：显示提示信息
      Get.snackbar(
        '提示',
        '登录已过期，请重新登录',
        snackPosition: SnackPosition.BOTTOM,
      );

      // 设置标志位，表示处理完成
      isHandling.value = false;
    });
  }

  @override
  Future<dynamic> realRequest<T>(
    String path, {
    String method = "POST",
    dynamic data,
    Map<String, dynamic>? queryParameters,
    Map<String, dynamic>? headers,
  }) async {
    // 发起网络请求
    // 设置默认的 contentType
    String? contentType;

    // 如果是 FormData 类型，不需要设置 contentType，Dio 会自动设置为 multipart/form-data
    // 否则默认使用 application/json
    if (data != null && !(data is dio.FormData)) {
      contentType = Headers.jsonContentType;
    }

    try {
      var response = await _dio.request(
        path,
        data: data,
        queryParameters: queryParameters,
        options: Options(
          method: method,
          headers: headers,
          contentType: contentType,
        ),
      );
      return response.data;
    } catch (err) {
      if (err is DioError) {
        if (err.response != null) {
          return err.response!.data;
        } else {
          return null;
        }
      } else {
        return null;
      }
    }
  }
}
